<!--
  密码安全输入组件
  集成RSA加密和密码强度检查功能
  
  使用示例：
  <PasswordSecurityInput
    v-model="password"
    placeholder="请输入密码"
    @encrypted="handleEncryptedPassword"
    @strength-change="handleStrengthChange"
  />
-->
<template>
  <div class="password-security-input">
    <!-- 密码输入框 -->
    <div class="input-wrapper">
      <el-input
        v-model="passwordValue"
        :type="showPassword ? 'text' : 'password'"
        :placeholder="placeholder"
        :disabled="disabled || encrypting"
        :size="size"
        :clearable="clearable"
        @input="handlePasswordInput"
        @blur="handlePasswordBlur"
        @focus="handlePasswordFocus"
        class="password-input"
      >
        <!-- 密码可见性切换 -->
        <template #suffix>
          <div class="suffix-icons">
            <el-icon
              @click="togglePasswordVisibility"
              class="password-toggle"
              :class="{ disabled: disabled }"
            >
              <View v-if="showPassword" />
              <Hide v-else />
            </el-icon>

            <!-- 加密状态指示器 -->
            <el-tooltip v-if="encryptionEnabled" :content="encryptionTooltip">
              <el-icon class="encryption-status" :class="encryptionStatusClass">
                <Lock />
              </el-icon>
            </el-tooltip>
          </div>
        </template>
      </el-input>

      <!-- 密码生成器按钮 -->
      <el-button
        v-if="showGenerator"
        size="small"
        type="primary"
        text
        @click="generatePassword"
        :loading="generating"
        class="generate-btn"
      >
        <el-icon><Refresh /></el-icon>
        生成强密码
      </el-button>
    </div>

    <!-- 密码强度指示器 -->
    <div
      v-if="showStrengthIndicator && (passwordValue || strengthResult)"
      class="strength-indicator"
    >
      <div class="strength-bar-container">
        <div class="strength-label">密码强度：</div>
        <div class="strength-bar">
          <div
            class="strength-fill"
            :style="{
              width: strengthPercentage + '%',
              backgroundColor: strengthColor,
            }"
          ></div>
        </div>
        <div class="strength-text" :style="{ color: strengthColor }">
          {{ strengthText }}
        </div>
      </div>

      <!-- 密码要求和建议 -->
      <div
        v-if="strengthResult && strengthResult.suggestions.length > 0"
        class="suggestions"
      >
        <div class="suggestions-title">建议改进：</div>
        <ul class="suggestions-list">
          <li
            v-for="suggestion in strengthResult.suggestions"
            :key="suggestion"
          >
            {{ suggestion }}
          </li>
        </ul>
      </div>

      <!-- 密码要求检查 -->
      <div v-if="showRequirements && strengthResult" class="requirements">
        <div class="requirements-title">密码要求：</div>
        <div class="requirements-list">
          <div
            class="requirement-item"
            :class="{ met: strengthResult.checks.length }"
          >
            <el-icon>
              <Check v-if="strengthResult.checks.length" />
              <Close v-else />
            </el-icon>
            至少8个字符
          </div>
          <div
            class="requirement-item"
            :class="{ met: strengthResult.checks.uppercase }"
          >
            <el-icon>
              <Check v-if="strengthResult.checks.uppercase" />
              <Close v-else />
            </el-icon>
            包含大写字母
          </div>
          <div
            class="requirement-item"
            :class="{ met: strengthResult.checks.lowercase }"
          >
            <el-icon>
              <Check v-if="strengthResult.checks.lowercase" />
              <Close v-else />
            </el-icon>
            包含小写字母
          </div>
          <div
            class="requirement-item"
            :class="{ met: strengthResult.checks.number }"
          >
            <el-icon>
              <Check v-if="strengthResult.checks.number" />
              <Close v-else />
            </el-icon>
            包含数字
          </div>
          <div
            class="requirement-item"
            :class="{ met: strengthResult.checks.special }"
          >
            <el-icon>
              <Check v-if="strengthResult.checks.special" />
              <Close v-else />
            </el-icon>
            包含特殊字符
          </div>
        </div>
      </div>
    </div>

    <!-- 加密错误提示 -->
    <div v-if="encryptionError" class="error-message">
      <el-icon><WarningFilled /></el-icon>
      {{ encryptionError }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from "vue";
import { ElMessage } from "element-plus";
import {
  View,
  Hide,
  Lock,
  Refresh,
  Check,
  Close,
  WarningFilled,
} from "@element-plus/icons-vue";
import passwordEncryption, {
  type PasswordStrengthResult,
  getPasswordStrengthColor,
  getPasswordStrengthText,
} from "../utils/passwordEncryption";

// Props定义
interface Props {
  modelValue?: string;
  placeholder?: string;
  disabled?: boolean;
  size?: "large" | "default" | "small";
  clearable?: boolean;
  encryptionEnabled?: boolean; // 是否启用加密
  showStrengthIndicator?: boolean; // 显示密码强度指示器
  showRequirements?: boolean; // 显示密码要求
  showGenerator?: boolean; // 显示密码生成器
  autoEncrypt?: boolean; // 失焦时自动加密
  strengthCheckDelay?: number; // 密码强度检查延迟（毫秒）
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: "",
  placeholder: "请输入密码",
  disabled: false,
  size: "default",
  clearable: true,
  encryptionEnabled: true,
  showStrengthIndicator: true,
  showRequirements: true,
  showGenerator: false,
  autoEncrypt: false,
  strengthCheckDelay: 500,
});

// Emits定义
interface Emits {
  (e: "update:modelValue", value: string): void;
  (e: "encrypted", encryptedPassword: string): void;
  (e: "strength-change", strengthResult: PasswordStrengthResult | null): void;
  (e: "focus"): void;
  (e: "blur"): void;
}

const emit = defineEmits<Emits>();

// 响应式数据
const passwordValue = ref(props.modelValue);
const showPassword = ref(false);
const encrypting = ref(false);
const generating = ref(false);
const encryptionError = ref("");
const strengthResult = ref<PasswordStrengthResult | null>(null);
const strengthCheckTimer = ref<number | null>(null);
const encryptionInitialized = ref(false);

// 计算属性
const strengthPercentage = computed(() => {
  if (!strengthResult.value) return 0;
  return (strengthResult.value.score / 5) * 100;
});

const strengthColor = computed(() => {
  if (!strengthResult.value) return "#dcdfe6";
  return getPasswordStrengthColor(strengthResult.value.strength);
});

const strengthText = computed(() => {
  if (!strengthResult.value) return "";
  return getPasswordStrengthText(strengthResult.value.strength);
});

const encryptionStatusClass = computed(() => ({
  "status-success": encryptionInitialized.value && !encryptionError.value,
  "status-error": !!encryptionError.value,
  "status-loading": encrypting.value,
}));

const encryptionTooltip = computed(() => {
  if (encrypting.value) return "正在加密...";
  if (encryptionError.value) return `加密错误: ${encryptionError.value}`;
  if (encryptionInitialized.value) return "传输加密已启用";
  return "正在初始化加密功能...";
});

// 监听props变化
watch(
  () => props.modelValue,
  (newValue) => {
    passwordValue.value = newValue;
  }
);

watch(passwordValue, (newValue) => {
  emit("update:modelValue", newValue);
});

// 组件挂载时初始化加密功能
onMounted(async () => {
  if (props.encryptionEnabled) {
    try {
      const success = await passwordEncryption.initialize();
      encryptionInitialized.value = success;
      if (!success) {
        encryptionError.value = "加密功能初始化失败";
      }
    } catch (error) {
      encryptionError.value =
        error instanceof Error ? error.message : "初始化错误";
    }
  }
});

// 密码输入处理
const handlePasswordInput = (value: string) => {
  passwordValue.value = value;
  encryptionError.value = "";

  // 防抖处理密码强度检查
  if (props.showStrengthIndicator) {
    if (strengthCheckTimer.value) {
      window.clearTimeout(strengthCheckTimer.value);
    }

    strengthCheckTimer.value = window.setTimeout(async () => {
      if (value.trim()) {
        const result = await passwordEncryption.checkPasswordStrength(value);
        strengthResult.value = result;
        emit("strength-change", result);
      } else {
        strengthResult.value = null;
        emit("strength-change", null);
      }
    }, props.strengthCheckDelay);
  }
};

// 密码框获得焦点
const handlePasswordFocus = () => {
  emit("focus");
};

// 密码框失去焦点
const handlePasswordBlur = async () => {
  emit("blur");

  // 自动加密选项
  if (props.autoEncrypt && props.encryptionEnabled && passwordValue.value) {
    await encryptPassword();
  }
};

// 切换密码可见性
const togglePasswordVisibility = () => {
  if (props.disabled) return;
  showPassword.value = !showPassword.value;
};

// 加密密码
const encryptPassword = async (): Promise<string | null> => {
  if (!props.encryptionEnabled || !passwordValue.value) {
    return null;
  }

  encrypting.value = true;
  encryptionError.value = "";

  try {
    const encryptedPassword = await passwordEncryption.encryptPassword(
      passwordValue.value
    );
    emit("encrypted", encryptedPassword);
    return encryptedPassword;
  } catch (error) {
    encryptionError.value = error instanceof Error ? error.message : "加密失败";
    ElMessage.error(`密码加密失败: ${encryptionError.value}`);
    return null;
  } finally {
    encrypting.value = false;
  }
};

// 生成强密码
const generatePassword = async () => {
  generating.value = true;

  try {
    const strongPassword = await passwordEncryption.generateStrongPassword(12);
    if (strongPassword) {
      passwordValue.value = strongPassword;
      ElMessage.success("强密码生成成功");
    } else {
      ElMessage.error("密码生成失败");
    }
  } catch (error) {
    ElMessage.error(
      `密码生成失败: ${error instanceof Error ? error.message : "未知错误"}`
    );
  } finally {
    generating.value = false;
  }
};

// 暴露给父组件的方法
defineExpose({
  encryptPassword,
  generatePassword,
  getStrengthResult: () => strengthResult.value,
  focus: () => {
    // 这里需要获取input元素的引用来调用focus方法
  },
});
</script>

<style lang="scss" scoped>
.password-security-input {
  width: 100%;

  .input-wrapper {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;

    .password-input {
      flex: 1;

      :deep(.el-input__suffix) {
        .suffix-icons {
          display: flex;
          align-items: center;
          gap: 4px;

          .password-toggle {
            cursor: pointer;
            color: #909399;
            transition: color 0.2s;

            &:hover:not(.disabled) {
              color: #409eff;
            }

            &.disabled {
              cursor: not-allowed;
              opacity: 0.5;
            }
          }

          .encryption-status {
            font-size: 14px;

            &.status-success {
              color: #67c23a;
            }

            &.status-error {
              color: #f56c6c;
            }

            &.status-loading {
              color: #409eff;
              animation: spin 1s linear infinite;
            }
          }
        }
      }
    }

    .generate-btn {
      flex-shrink: 0;
    }
  }

  .strength-indicator {
    margin-top: 8px;
    padding: 8px;
    background: #f5f7fa;
    border-radius: 4px;
    font-size: 12px;

    .strength-bar-container {
      display: flex;
      align-items: center;
      gap: 8px;
      margin-bottom: 8px;

      .strength-label {
        color: #606266;
        white-space: nowrap;
      }

      .strength-bar {
        flex: 1;
        height: 6px;
        background: #e4e7ed;
        border-radius: 3px;
        overflow: hidden;

        .strength-fill {
          height: 100%;
          transition: all 0.3s ease;
          border-radius: 3px;
        }
      }

      .strength-text {
        font-weight: 500;
        white-space: nowrap;
        transition: color 0.3s ease;
      }
    }

    .suggestions {
      margin-bottom: 8px;

      .suggestions-title {
        color: #909399;
        margin-bottom: 4px;
        font-size: 11px;
      }

      .suggestions-list {
        margin: 0;
        padding-left: 16px;
        color: #f56c6c;

        li {
          margin-bottom: 2px;
        }
      }
    }

    .requirements {
      .requirements-title {
        color: #909399;
        margin-bottom: 4px;
        font-size: 11px;
      }

      .requirements-list {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
        gap: 2px;

        .requirement-item {
          display: flex;
          align-items: center;
          gap: 4px;
          color: #f56c6c;
          font-size: 11px;

          &.met {
            color: #67c23a;
          }

          .el-icon {
            font-size: 10px;
          }
        }
      }
    }
  }

  .error-message {
    margin-top: 4px;
    padding: 4px 8px;
    background: #fef0f0;
    border: 1px solid #fde2e2;
    border-radius: 4px;
    color: #f56c6c;
    font-size: 12px;
    display: flex;
    align-items: center;
    gap: 4px;

    .el-icon {
      flex-shrink: 0;
    }
  }
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>